package org.dromara.datacheck.listener;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.excel.core.ExcelListener;
import org.dromara.common.excel.core.ExcelResult;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.datacheck.domain.bo.JdAndJstMapBo;
import org.dromara.datacheck.domain.vo.JdAndJstMapImportVo;
import org.dromara.datacheck.service.IJdAndJstMapService;

import java.util.List;


/**
 * @Author 刘武贵
 * @Date 2024/8/15 22:00
 * @Description 功能描述：金蝶和聚水潭映射导入监听器
 * 金蝶-销售出库单导入监听器类，用于处理Excel数据的导入事件
 * 继承自AnalysisEventListener，并实现ExcelListener接口，专用于处理JdSaleOutWarehouseOrderImportVo类型的Excel数据导入事件
 * 该类的主要作用是监听并处理Excel数据导入过程中的各种事件，如准备读取数据、读取每行数据、读取完毕等
 */
@Slf4j
public class JdAndJstMapImportListener extends AnalysisEventListener<JdAndJstMapImportVo> implements ExcelListener<JdAndJstMapImportVo> {

    /**
     * 金蝶和聚水潭映射 业务层
     */
    private final IJdAndJstMapService jdAndJstMapService;

    /**
     * 表示是否支持更新操作的标志，通常用于特定的业务场景或配置
     */
    private final Boolean isUpdateSupport;

    /**
     * 操作用户ID，用于记录执行操作的用户信息
     */
    private final Long operateUserId;

    /**
     * 成功操作的数量，用于统计操作成功的次数
     */
    private int successNum = 0;

    /**
     * 失败操作的数量，用于统计操作失败的次数
     */
    private int failureNum = 0;

    /**
     * 存储成功操作的消息，使用StringBuilder动态拼接消息内容
     */
    private final StringBuilder successMsg = new StringBuilder();

    /**
     * 存储失败操作的消息，使用StringBuilder动态拼接消息内容
     */
    private final StringBuilder failureMsg = new StringBuilder();


    /**
     * 构造函数：初始化金蝶和聚水潭映射导入监听器
     * 本构造函数用于初始化JdAndJstMapImportListener对象它会在对象创建时执行以下操作：
     * 1. 获取jdAndJstMapService bean用于后续的用户信息查询和保存操作
     * 2. 设置是否支持更新已存在的信息
     * 3. 获取当前操作用户的ID，通常用于审计目的
     *
     * @param isUpdateSupport 是否支持更新已存在的用户信息
     */
    public JdAndJstMapImportListener(Boolean isUpdateSupport) {
        // 获取jdAndJstMapService bean，用于用户信息的查询和保存
        this.jdAndJstMapService = SpringUtils.getBean(IJdAndJstMapService.class);
        // 设置是否支持更新已存在的信息
        this.isUpdateSupport = isUpdateSupport;
        // 获取当前登录用户的ID和名称，用于可能的审计操作
        this.operateUserId = LoginHelper.getUserId();
    }

    /**
     * 处理Excel导入事件
     * 该方法首先检查用户是否已存在
     *
     * @param jdAndJstMapImportVo 包含要导入或更新的用户信息
     * @param context                         提供对解析上下文的访问
     */
    @Override
    public void invoke(JdAndJstMapImportVo jdAndJstMapImportVo, AnalysisContext context) {
        try {
            JdAndJstMapBo jdAndJstMapBo = BeanUtil.toBean(jdAndJstMapImportVo, JdAndJstMapBo.class);
            jdAndJstMapBo.setCreateBy(operateUserId);
            jdAndJstMapService.insertByBo(jdAndJstMapBo);
            successNum++;
        } catch (Exception e) {
            failureNum++;
            String msg = "数据格式错误，导入失败";
            log.error(msg, e);
        }
    }

    /**
     * 在所有分析完成后执行的操作
     * 此方法被框架调用，用于处理分析完成后需要进行的操作
     *
     * @param context 分析上下文，包含所有分析相关的必要信息和数据
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 此处的方法体可以包含在所有数据分析完成后需要执行的逻辑
    }

    /**
     * 实现getExcelResult方法，返回ExcelResult对象，用于处理Excel导入的结果
     *
     * @return 返回ExcelResult对象，包含导入成功或失败的信息及详情
     */
    @Override
    public ExcelResult<JdAndJstMapImportVo> getExcelResult() {
        return new ExcelResult<>() {

            /**
             * 获取导入分析结果的方法
             * 此方法会根据失败数量判断并抛出异常，或者返回成功消息
             * @return 返回分析消息字符串
             * @throws ServiceException 若存在导入失败的数据，抛出ServiceException，携带失败消息
             */
            @Override
            public String getAnalysis() {
                if (failureNum > 0) {
                    failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确");
                    throw new ServiceException(failureMsg.toString());
                } else {
                    successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条,请和你导入的excel比对看总条数是否正确！");
                }
                return successMsg.toString();
            }

            /**
             * 获取导入成功的数据列表
             * 此方法中直接返回null，表示不提供具体的数据列表
             * @return 返回null，表示没有提供导入成功的数据列表
             */
            @Override
            public List<JdAndJstMapImportVo> getList() {
                return null;
            }

            /**
             * 获取导入错误信息的列表
             * 此方法中直接返回null，表示不提供具体的错误信息列表
             * @return 返回null，表示没有提供错误信息列表
             */
            @Override
            public List<String> getErrorList() {
                return null;
            }
        };
    }
}
